#include <malloc.h>
#include <string.h>

#include "jinju_remote_processor.h"
#include "asc_decoder-apk.h"

#define JINJU_RMT_CODEC ASC_I_16KHz_16BIT_MONO_16KBPS
#define SAMPLESLEN 320
#define HALF_SAMPLESLEN SAMPLESLEN/2

static unsigned char ss_aay[20]={0xA8, 0x25,0x3f,0x97,0x4e,0xb9,0x1f,0xc7,0x39,0x6d,0x1c,0xab,
                                 0x17,0x95,0x3e,0x9f, 0x5c, 0x28, 0x8a, 0x11};

int isJJProcessing = 0;
int mBitstreamlen = 0;
int mWaitBufCnt = 0;

process_callback_p mPcb;
char *mInbuf;
short *mOutbuf;
//char *mDecryptOut;

int mmf_decrypt(unsigned char *indata, unsigned char *outdata, unsigned int len)
{
    unsigned int i;
    if (len != 20)
        return -1;

    for (i = 0; i < len; i++) {
        outdata[i] = indata[i] ^ ss_aay[i];
    }
    return 0;
}

int jinju_rmt_init(process_callback_p pcb) {
    LOGD("+ jinju_rmt_init ");
    if (isJJProcessing) {
        LOGD("jinju remote already init");
        return 0;
    }

    if (pcb) {
        mPcb = pcb;
    } else {
        return -1;
    }

    mBitstreamlen = ASC_Decoder_Init(JINJU_RMT_CODEC);
    LOGD("Bitstreamlen = %d", mBitstreamlen);
    if (mBitstreamlen <= 0) {
        LOGE("ASC_Decoder_Init err: %d", mBitstreamlen);
        return -2;
    }
//    ASC_Set_Parameter (agc, ns);//open agc and nr, must after ASC_Decoder_Init
    mOutbuf = calloc(SAMPLESLEN, sizeof(short));
    mInbuf = calloc((size_t) mBitstreamlen, sizeof(short));
//    mDecryptOut = calloc((size_t) mBitstreamlen, sizeof(char));
//    if (!mOutbuf || !mInbuf || !mDecryptOut) {
    if (!mOutbuf || !mInbuf) {
        LOGE("jinju_rmt_init buffer calloc err");
        return -3;
    }

    mWaitBufCnt = 0;
    isJJProcessing = 1;
    LOGD("- jinju_rmt_init ");
    return 0;
}

int jinju_rmt_process(char *buf, int len) {
//    LOGD("jinju_rmt_process buf len = %d", len);
    if (mPcb && (len == mBitstreamlen)) {
        short samplelen = 0;
        if (mWaitBufCnt) {
            mmf_decrypt((unsigned char *) buf, ((unsigned char *) mInbuf + mBitstreamlen), (unsigned int) len);

            samplelen = ASC_Decoder((short *) mInbuf, mOutbuf, (short) mBitstreamlen, JINJU_RMT_CODEC);
            if (samplelen <= 0) {
                LOGE("jinju_rmt_process decode err: %d", samplelen);
                return -1;
            }
//            LOGD("jinju_rmt_process samplelen = %d", samplelen);
            mPcb->onProcessBuffer((unsigned char *) mOutbuf, samplelen * sizeof(short));
            mWaitBufCnt = 0;
        } else {
            mmf_decrypt((unsigned char *) buf, (unsigned char *) mInbuf, (unsigned int) len);
//            memcpy(mInbuf, mDecryptOut, (size_t) len);
            mWaitBufCnt = 1;
        }
    }
    return 0;
}

int jinju_rmt_destroy() {
    LOGD("jinju_rmt_destroy");
    isJJProcessing = 0;
    if (mOutbuf) {
        free(mOutbuf);
    }
    return 0;
}

